package com.ruoyi.common.utils.wxpay;


import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.util.SignUtils;
import com.google.common.collect.Maps;
import com.ruoyi.api.ApiConstants;
import com.ruoyi.framework.dto.AuthTokenException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Map;
import java.util.TreeMap;


/**微信支付相关封装
 * @author ywh
 * @date 2021/5/24
 * @desc
 */
@Service
public class WeChatService {

    @Autowired
    private  WxPayService wxPayService;

    public Map jsApiPreparyId(BigDecimal orderPrice,String orderNo,Long orderId,String openid,String notifyUrl) {
        try {
            WxPayUnifiedOrderRequest wxPayRequest = new WxPayUnifiedOrderRequest();
            wxPayRequest.setOutTradeNo(orderNo);
            wxPayRequest.setBody("支付订单");
            wxPayRequest.setTotalFee(orderPrice.multiply(new BigDecimal(100)).intValue());//元转成分
            wxPayRequest.setAttach(String.valueOf(orderId));
            wxPayRequest.setSpbillCreateIp(ApiConstants.SPBILL_CREATE_IP);
            wxPayRequest.setOpenid(openid);
            wxPayRequest.setNotifyUrl(notifyUrl);
            wxPayRequest.setTradeType("JSAPI");
            WxPayUnifiedOrderResult wxPayResult = wxPayService.unifiedOrder(wxPayRequest);
            Map<String, String> resultMap = new TreeMap<>();//装载返回给页面的参数
            if (wxPayResult.getReturnCode().equalsIgnoreCase("FAIL")) {
                //接口调用失败
                throw new AuthTokenException("调接口失败：" + wxPayResult.getReturnMsg(),1);
            } else if (wxPayResult.getReturnCode().equalsIgnoreCase("SUCCESS")) {
                String result_code = wxPayResult.getResultCode();//返回结果标识
                if (result_code.equalsIgnoreCase("FAIL")) {
                    throw new AuthTokenException("获取预支付id失败",1);
                } else if (result_code.equalsIgnoreCase("SUCCESS")) {
                    //app支付需要返回参数
                    resultMap.put("appId", wxPayResult.getAppid()); // 先生成paySign参数map
                    resultMap.put("package", "prepay_id=" + wxPayResult.getPrepayId());
                    //resultMap.put("noncestr", WXArgHandleUtil.generateNonceStr()); //获取随机字符串
                    resultMap.put("nonceStr", OrderUtil.getNonceStr()); //获取随机字符串
                    resultMap.put("timeStamp", String.valueOf(System.currentTimeMillis()).substring(0, 10));  //时间戳
                    resultMap.put("signType", "MD5");
                    //String sign = WXArgHandleUtil.generateSignature(resultMap, ApiConstants.PAYKEY, WXPayConstants.SignType.MD5);
                    String sign = SignUtils.createSign(resultMap,"MD5", ApiConstants.PAYKEY,new String[0]);
                    resultMap.put("paySign", sign); //此处根据返回的结果，和预支付id在此生成支付签证
                    resultMap.put("orderId", String.valueOf(orderId)); //此处根据返回的结果，和预支付id在此生成支付签证
                    return resultMap;
                } else {
                    throw new AuthTokenException("获取预支付id失败",1);
                }
            } else {
                throw new AuthTokenException("调接口失败：" + wxPayResult.getReturnMsg(),1);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new AuthTokenException(e.getMessage(),1);
        }
    }



    /**
     * APP支付
     * @param orderPrice
     * @param payNo
     * @param orderId
     * @param notifyUrl
     * @return
     */
    public  Map toAppPay(BigDecimal orderPrice, String payNo, Long orderId,String notifyUrl) {
        try {
            WxPayUnifiedOrderRequest wxPayRequest = new WxPayUnifiedOrderRequest();
            wxPayRequest.setBody("课程购买");
            wxPayRequest.setOutTradeNo(payNo);
            wxPayRequest.setTotalFee(orderPrice.multiply(new BigDecimal(100)).intValue());//元转成分
            wxPayRequest.setAttach(String.valueOf(orderId));
            wxPayRequest.setSpbillCreateIp(ApiConstants.SPBILL_CREATE_IP);
            wxPayRequest.setNotifyUrl(notifyUrl);
            wxPayRequest.setTradeType("APP");
            WxPayUnifiedOrderResult wxPayResult = wxPayService.unifiedOrder(wxPayRequest);
            Map<String, String> resultMap = new TreeMap<>();//装载返回给页面的参数
            if (wxPayResult.getReturnCode().equalsIgnoreCase("FAIL")) {  //接口调用失败
                throw new AuthTokenException("调接口失败：" + wxPayResult.getReturnMsg(),1);
            } else if (wxPayResult.getReturnCode().equalsIgnoreCase("SUCCESS")) {
                String result_code = wxPayResult.getResultCode();//返回结果标识
                if (result_code.equalsIgnoreCase("FAIL")) {
                    throw new AuthTokenException("获取预支付id失败",1);
                } else if (result_code.equalsIgnoreCase("SUCCESS")) {
                    //app支付需要返回参数
                    resultMap.put("prepayid", wxPayResult.getPrepayId());  //统一下单成成之后返回的prepay_id
                    resultMap.put("appid", wxPayResult.getAppid()); // 先生成paySign参数map
                    resultMap.put("partnerid", ApiConstants.MCH_ID); // 商户号
                    resultMap.put("package", "Sign=WXPay");  //APP使用
                    //resultMap.put("noncestr", WXArgHandleUtil.generateNonceStr()); //获取随机字符串
                    resultMap.put("noncestr", OrderUtil.getNonceStr()); //获取随机字符串
                    resultMap.put("timestamp", String.valueOf(System.currentTimeMillis()).substring(0, 10));  //时间戳
                    //String sign = WXArgHandleUtil.generateSignature(resultMap, ApiConstants.PAYKEY, WXPayConstants.SignType.MD5);
                    String sign = SignUtils.createSign(resultMap,"MD5", ApiConstants.PAYKEY,new String[0]);
                    resultMap.put("paySign", sign); //此处根据返回的结果，和预支付id在此生成支付签证
                    return resultMap;
                } else {
                    throw new AuthTokenException("获取预支付id失败",1);
                }
            } else {
                throw new AuthTokenException("调接口失败：" + wxPayResult.getReturnMsg(),1);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new AuthTokenException("系统错误",1);
        }
    }


    /**
     * 退款操作
     */
    public WxPayRefundResult refundOrder(BigDecimal orderPrice,String trateNo,String refundNo) {
        WxPayRefundResult result;
        try {
            WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
            wxPayRefundRequest.setTransactionId(trateNo);
            wxPayRefundRequest.setOutRefundNo(refundNo);
            wxPayRefundRequest.setTotalFee(orderPrice.multiply(new BigDecimal(100)).intValue());
            wxPayRefundRequest.setRefundFee(orderPrice.multiply(new BigDecimal(100)).intValue());
            wxPayRefundRequest.setNotifyUrl(ApiConstants.REFUND_NOTIFY_URL);
            result = wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            throw new AuthTokenException(e.getReturnMsg(),1);
        }
        return result;
    }




    /**
     * 微信提现到零钱
     * @param pickMoney
     * @param openId
     * @return
     * @throws Exception
     */
    public EntPayResult toPickWeChat(BigDecimal pickMoney, String openId) throws Exception {
        EntPayRequest entPayRequest = new EntPayRequest();
        entPayRequest.setAppid(ApiConstants.APPID);
        entPayRequest.setMchId(ApiConstants.MCH_ID);
        entPayRequest.setPartnerTradeNo(OrderUtil.getGoodsOrderNo());
        entPayRequest.setOpenid(openId);
        entPayRequest.setCheckName("NO_CHECK");
        entPayRequest.setAmount(pickMoney.multiply(new BigDecimal(100)).intValue());
        entPayRequest.setDescription("余额提现");
        entPayRequest.setSpbillCreateIp(ApiConstants.SPBILL_CREATE_IP);
        EntPayResult entPayResult = null;
        try {
            //此处调用=============================================================
            // 通过Java配置来实例化Spring容器
            entPayResult= wxPayService.getEntPayService().entPay(entPayRequest);
        } catch (WxPayException e) {
            throw new AuthTokenException(e.getCustomErrorMsg());
        }
        return entPayResult;
    }

}
